

function CreatePhysics ( )
    SetPhysicsGravity (0,400)
    SetPhysicsWallLeft (0)
    SetPhysicsWallRight (0)
endfunction

function CreateArena ( )

    // Start arena
    arenaTimer# = Timer ( )
    if g_iSky = 0
        g_iSky = CreateSprite ( g_iSkyImage )
        SetSpriteDepth ( g_iSky, 20)
    endif
    // Reset platform queue
    ResetPlatformQueue ( )
    // Create platforms
    AddToPlatformQueue ( pLarge,    0,      736 )
    AddToPlatformQueue ( pLarge,    256,    736 )
    AddToPlatformQueue ( pLarge,    512,    736 )
    AddToPlatformQueue ( pLarge,    768,    736 )
    AddToPlatformQueue ( pMedium,   320,    608 )
    AddToPlatformQueue ( pMedium,   576,    544 )
    AddToPlatformQueue ( pSmall,    0,    64  )
    AddToPlatformQueue ( pMedium,   256,    512 )
    AddToPlatformQueue ( pSmall,    768,    64  )
    AddToPlatformQueue ( pMedium,   256,    256  )
    AddToPlatformQueue ( pMedium,   0,      384 )
    AddToPlatformQueue ( pLarge,    128,      160 )
    remstart
    CreatePlatform ( TopLeft  , "arena/LeftTop.png"  ,   0,  80 )
    CreatePlatform ( TopMid   , "arena/MidTop.png"   , 220, 140 )
    CreatePlatform ( TopRight , "arena/RightTop.png" , 672,  80 )
    CreatePlatform ( BotLeft  , "arena/LeftBot.png"  ,   0, 260 )
    CreatePlatform ( BotMid   , "arena/MidBot.png"   , 270, 330 )
    CreatePlatform ( BotRight , "arena/RightBot.png" , 710, 260 )
    CreatePlatform ( BotRight2, "arena/RightBot2.png", 600, 236 )
    CreatePlatform ( Base     , "arena/Base.png"     ,   0, 435 )
    remend
    // Create spawners
    CreateSpawner ( 1, 336, 435 )
    CreateSpawner ( 2, 336, 140 )
    // Reset the spawn queue
    ResetSpawnQueue ( )
    // Spawn the player
    AddToSpawnQueue ( -1 )
    // Spawn Wave 1 of enemies
    //AddToSpawnQueue ( 1 )
    //AddToSpawnQueue ( 1 )
    //AddToSpawnQueue ( 1 )
    //AddToSpawnQueue ( 1 )
endfunction

function CreatePlatform ( pType, X, Y )
    for index = 1 to MaxPlats
        if g_iPlatform [ index ].Sprite = 0
            select ( pType )

            case pSmall:
                // Setup Platform sprite
                g_iPlatform [ index ].Sprite = CreateSprite ( g_iPlatformImage [ pType ] )
                SetSpritePosition   ( g_iPlatform [ index ].Sprite, X, 768 + 32 + 64 )
                // Setup Balloon sprites
                g_iPlatform [ index ].Balloon1 = MakeBalloon ( X + 32 )
                //
                g_iPlatform [ index ].Balloon2 = MakeBalloon ( X + 32 )
                // Setup String sprites
                g_iPlatform [ index ].String1 = CreateSprite ( g_iStringImage )
                SetSpritePosition   ( g_iPlatform [ index].String1, X + 32 + 32, 768 + 64 )
                g_iPlatform [ index ].String2 = CreateSprite ( g_iStringImage )
                SetSpritePosition   ( g_iPlatform [ index].String2, X + 32 + 32, 768 + 64 )
                // Initialize platform
                g_iPlatform [ index ].TargetY = Y
                g_iPlatform [ index ].State = Spawning
            endcase

            case pMedium:
                // Setup Platform sprite
                g_iPlatform [ index ].Sprite = CreateSprite ( g_iPlatformImage [ pType ] )
                SetSpritePosition   ( g_iPlatform [ index ].Sprite, X, 768 + 32 + 64 )
                // Setup Balloon sprites
                g_iPlatform [ index ].Balloon1 = MakeBalloon ( X + 64 )
                g_iPlatform [ index ].Balloon2 = MakeBalloon ( X + 64 )
                // Setup String sprites
                g_iPlatform [ index ].String1 = CreateSprite ( g_iStringImage )
                SetSpritePosition   ( g_iPlatform [ index].String1, X + 64 + 32 , 768 + 32 )
                g_iPlatform [ index ].String2 = CreateSprite ( g_iStringImage )
                SetSpritePosition   ( g_iPlatform [ index].String2, X + 64 + 32, 768 + 32 )
                // Initialize platform
                g_iPlatform [ index ].TargetY = Y
                g_iPlatform [ index ].State = Spawning
            endcase

            case pLarge:
                // Setup Platform sprite
                g_iPlatform [ index ].Sprite = CreateSprite ( g_iPlatformImage [ pType ] )
                SetSpritePosition   ( g_iPlatform [ index ].Sprite, X, 768 + 32 + 64 )
                // Setup Balloon sprites
                g_iPlatform [ index ].Balloon1 = MakeBalloon ( X + 32 )
                g_iPlatform [ index ].Balloon2 = MakeBalloon ( X + 160 )
                // Setup String sprites
                g_iPlatform [ index ].String1 = CreateSprite ( g_iStringImage )
                SetSpritePosition   ( g_iPlatform [ index].String1, X + 32 + 32, 768 + 32 )
                g_iPlatform [ index ].String2 = CreateSprite ( g_iStringImage )
                SetSpritePosition   ( g_iPlatform [ index].String2, X + 160 + 32, 768 + 32 )
                // Initialize platform
                g_iPlatform [ index ].TargetY = Y
                g_iPlatform [ index ].State = Spawning
            endcase

            endselect

            SetSpriteDepth ( g_iPlatform [ index ].Sprite, 9 )
            exitfunction
        endif
    next index
endfunction

function MakeBalloon ( X )
    Balloon = CreateSprite ( 0 )
    AddSpriteAnimationFrame ( Balloon, g_iBalloonImage [ 1 ] )
    AddSpriteAnimationFrame ( Balloon, g_iBalloonImage [ 2 ] )
    AddSpriteAnimationFrame ( Balloon, g_iBalloonImage [ 3 ] )
    AddSpriteAnimationFrame ( Balloon, g_iBalloonImage [ 4 ] )
    SetSpritePosition   ( Balloon, X, 768 )
    PlaySprite ( Balloon, 4 )
endfunction Balloon

function UpdatePlatform ( index )
    select ( g_iPlatform [ index ].State )

        case Spawning:
            y# = GetSpriteY ( g_iPlatform [ index ].Sprite )
            if y# > g_iPlatform [ index ].TargetY
                y# = y# - 200 * difference#
                SetSpriteY ( g_iPlatform [ index ].Sprite, y#)
                SetSpriteY ( g_iPlatform [ index ].Balloon1, y# - 32 - 64 )
                SetSpriteY ( g_iPlatform [ index ].Balloon2, y# - 32 - 64 )
                SetSpriteY ( g_iPlatform [ index ].String1, y# - 32 )
                SetSpriteY ( g_iPlatform [ index ].String2, y# - 32 )
            else
                SetSpriteY ( g_iPlatform [index ].Sprite, g_iPlatform [ index ].TargetY )
                SetSpriteDepth ( g_iPlatform [ index ].Sprite, 9 )
                SetSpriteDepth ( g_iPlatform [ index ].Balloon1, 11 )
                SetSpriteDepth ( g_iPlatform [ index ].Balloon2, 11 )
                SetSpriteDepth ( g_iPlatform [ index ].String1, 11 )
                SetSpriteDepth ( g_iPlatform [ index ].String2, 11 )
                SetupPhysicsForPlatform ( g_iPlatform [ index ].Sprite )
                g_iPlatform [ index ].State = Idle
            endif
        endcase

        case Dying:
            SetSpriteY ( g_iPlatform [ index ].Sprite, GetSpriteY ( g_iPlatform [ index ].Sprite ) + 100 * g_iPlatform [ index ].TargetY * difference# )
            SetSpriteY ( g_iPlatform [ index ].Balloon1, GetSpriteY ( g_iPlatform [ index ].Balloon1 ) - 100 * g_iPlatform [ index ].TargetY * difference# )
            SetSpriteY ( g_iPlatform [ index ].Balloon2, GetSpriteY ( g_iPlatform [ index ].Balloon2 ) - 100 * g_iPlatform [ index ].TargetY * difference# )
            g_iPlatform [ index ].TargetY = g_iPlatform [ index ].TargetY + 0.2

            if GetSpriteY ( g_iPlatform [ index ].Sprite ) > 768 and GetSpriteY ( g_iPlatform [ index ].Balloon1 ) < 0
                DestroyPlatform ( index )
                g_iPlatform [ index ].State = Idle
            endif
        endcase

    endselect
endfunction

function KillPlatform ( index )
    if g_iPlatform [ index ].Sprite <> 0
        g_iPlatform [ index ].State = Dying
        SetSpritePhysicsDelete ( g_iPlatform [ index ].Sprite )
        g_iPlatform [ index ].TargetY = 1
        DeleteSprite ( g_iPlatform [ index ].String1 )
        DeleteSprite ( g_iPlatform [ index ].String2 )
    endif
endfunction

function DestroyPlatform ( index )
    if GetSpriteExists ( g_iPlatform [ index ].Sprite )
        DeleteSprite ( g_iPlatform [ index ].Sprite )
        DeleteSprite ( g_iPlatform [ index ].Balloon1 )
        DeleteSprite ( g_iPlatform [ index ].Balloon2 )
    endif
endfunction

function SetupPhysicsForPlatform ( whichPlatform )
    SetSpriteShape     ( whichPlatform, 3 )
    SetSpritePhysicsOn ( whichPlatform, 1 )
    SetSpriteGroup     ( whichPlatform, -1 )
endfunction

function CreateSpawner ( iD, X, Y )
    g_iSpawner [ iD ] = CreateSprite ( g_iSpawnerImage )
    SetSpritePosition ( g_iSpawner [ iD ], X, Y )
    SetSpriteDepth    ( g_iSpawner [ iD ], 8    )
endfunction

function ResetSpawnQueue ( )
    for index = 1 to QSize
        g_iSpawnQueue [ index ] = 0
    next index
endfunction

function ResetPlatformQueue ( )
    for index = 1 to pQSize
        g_iPlatformQueue [ index ].pType = 0
    next index
endfunction

function AddToSpawnQueue ( sType )
    for index = 1 to QSize
        if g_iSpawnQueue [ index ] = 0
            g_iSpawnQueue [ index ] = sType
            exitfunction
        endif
    next index
endfunction

function AddToPlatformQueue ( pType, X, Y )
    for index = 1 to pQSize
        if g_iPlatformQueue [ index ].pType = 0
            g_iPlatformQueue [ index ].pType = pType
            g_iPlatformQueue [ index ].X = X
            g_iPlatformQueue [ index ].Y = Y
            exitfunction
        endif
    next index
endfunction

function SpawnFromSpawnQueue ( )
    for index = 1 to QSize
        if g_iSpawnQueue [ index ] > 0
            CreateEnemy ( )
            g_iSpawnQueue [ index ] = 0
            exitfunction
        endif
        if g_iSpawnQueue [ index ] = -1
            CreatePlayer ( )
            g_iSpawnQueue [ index ] = 0
            exitfunction
        endif
    next index
endfunction

function PlatformFromPlatformQueue ( )
    for index = 1 to pQSize
        if g_iPlatformQueue [ index ].pType <> 0
            CreatePlatform ( g_iPlatformQueue [ index ].pType, g_iPlatformQueue [ index ].X, g_iPlatformQueue [ index ].Y )
            g_iPlatformQueue [ index ].pType = 0
            exitfunction
        endif
    next index
endfunction

function UpdateArena ( )
    if thisFrame# - arenaTimer > 0.3
        PlatformFromPlatformQueue ( )
        arenaTimer = thisFrame#
    endif
    if thisFrame# - g_iSpawnerTimer > .25
        if CheckForSpawn ( ) = 0 then SpawnFromSpawnQueue ( )
        g_iSpawnerTimer = thisFrame#
    endif
    for index = 1 to MaxPlats
        if g_iPlatform [ index ].Sprite <> 0 then UpdatePlatform ( index )
    next index

    if gameTimer# > 10.0 and gameTimer# < 10.1
        KillPlatform ( 12 )
        KillPlatform ( 5 )
        KillPlatform ( 1 )
        KillPlatform ( 4 )
    endif
endfunction

function FindAvailableSpawner ( )
    index = random (1, MaxSpawners )
    if SpriteRayCastGroup ( 2, GetSpriteXByOffset ( g_iSpawner [ index ] ), GetSpriteYByOffset ( g_iSpawner [ index ] ), GetSpriteXByOffset ( g_iSpawner [ index ] ), GetSpriteYByOffset ( g_iSpawner [ index ] ) - 100 ) = 0
        exitfunction index
    endif
endfunction 0
